package com.darryring.libcore.android.media;


import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Process;
import android.view.SurfaceHolder;

import com.darryring.libcore.Fast;
import com.darryring.libcore.media.Media;
import com.darryring.libcore.media.MediaListener;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by Darry.Ring on 15/12/11.
 */
public class AndroidMedia implements Media<SurfaceHolder,MediaPlayer>,Runnable{


    private static final class MediaTask{
        public byte what;
        public String value;
        public Object obj;
        public SurfaceHolder screen;
        public boolean video;
    }
    MediaPlayer mMediaPlayer;

    private boolean running;

    private String TAG="AndroidMedia";

    private String VERSION="1.0.0";

    private static final byte TASK_MEDIA_OPEN_URI    =     (byte)1;
    private static final byte TASK_MEDIA_START   =     (byte)2;
    private static final byte TASK_MEDIA_PAUSE   =     (byte)3;
    private static final byte TASK_MEDIA_STOP   =     (byte)4;
    private static final byte TASK_MEDIA_RELEASE =    (byte)5;
    private static final byte TASK_MEDIA_EXIT    =     (byte)9;


    LinkedBlockingQueue<MediaTask> basket = new LinkedBlockingQueue<MediaTask>();

    List<MediaListener> mMediaListeners = new ArrayList<MediaListener>();

    Context mContext;

    public AndroidMedia(Context ctx){
        mContext = ctx;
    }
    private void startTask(){
        if(!running){
            Thread t = new Thread(this);
            t.start();
        }
    }
    @Override
    public MediaPlayer getPlayer() {
        if(mMediaPlayer==null){
            mMediaPlayer = new MediaPlayer();
        }
        return mMediaPlayer;
    }

    /**
     * @param _uri
     * @param video
     */
    @Override
    public void openMediaAsyn(String _uri, boolean video,SurfaceHolder screen) {
        startTask();
        MediaTask _task = new MediaTask();
        _task.value = _uri;
        _task.video = video;
        _task.screen = screen;
        _task.what = TASK_MEDIA_OPEN_URI;
        basket.add(_task);
    }

    /**
     *
     */
    @Override
    public void pause() {
        startTask();
        MediaTask _task = new MediaTask();
        _task.what = TASK_MEDIA_PAUSE;
        basket.add(_task);

    }

    /**
     *
     */
    @Override
    public void start() {
        startTask();
        MediaTask _task = new MediaTask();
        _task.what = TASK_MEDIA_START;
        basket.add(_task);

    }

    /**
     *
     */
    @Override
    public void stop() {
        startTask();
        MediaTask _task = new MediaTask();
        _task.what = TASK_MEDIA_STOP;
        basket.add(_task);
    }

    /**
     * @param _call
     */
    @Override
    public void addMediaListener(MediaListener _call) {
        if(_call==null){
            return;
        }
        if(mMediaListeners.indexOf(_call)==-1){
            mMediaListeners.add(_call);
        }
    }

    /**
     * @param _call
     */
    @Override
    public void removeMediaListener(MediaListener _call) {
        if(_call==null){
            return;
        }
        if(mMediaListeners.indexOf(_call)!=-1){
            mMediaListeners.remove(_call);
        }
    }
    private synchronized void openMedia(final MediaTask _task){
        //-------------------------------------------------------------
        try {
            //
            if(UriType.isAssetsUriType(_task.value)){
                String newUri = _task.value.replace("assets://","");
                AssetManager _am = mContext.getAssets();
                AssetFileDescriptor _descriptors = _am.openFd(newUri);
                mMediaPlayer.setDataSource(_descriptors.getFileDescriptor(),_descriptors.getStartOffset(),_descriptors.getLength());
//                mMediaPlayer.setDataSource(_descriptors.getFileDescriptor());

            }else if(UriType.isHttpUriType(_task.value)) {
                mMediaPlayer.setDataSource(mContext, Uri.parse(_task.value), null);
            }else if(UriType.isFileUriType(_task.value)){
                String newUri = _task.value.replace("file://","");
                mMediaPlayer.setDataSource(mContext,Uri.parse(newUri));
            }
            if(_task.video){
                if(_task.screen!=null){
                    mMediaPlayer.setDisplay(_task.screen);
                }
            }
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mMediaPlayer.setScreenOnWhilePlaying(true);
            mMediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }catch(Exception ex){
            ex.printStackTrace();
        }

    }
    @Override
    public synchronized void run() {
        Fast.logger.d(TAG, "running...");
        running = true;
        android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
        while (running) {
            try {
                MediaTask _mMediaTask = basket.take();
                switch(_mMediaTask.what){
                    case TASK_MEDIA_EXIT:
                        running = false;
                        break;
                    case TASK_MEDIA_OPEN_URI:
                        openMedia(_mMediaTask);
                        break;
                    case TASK_MEDIA_START:
                        mMediaPlayer.start();
                        break;
                    case TASK_MEDIA_PAUSE:
                        mMediaPlayer.pause();
                        break;
                    case TASK_MEDIA_STOP:
                        mMediaPlayer.stop();
                        mMediaPlayer.release();;
                        break;
                    case TASK_MEDIA_RELEASE:
                        reset();
                        if(mMediaPlayer!=null){
                            mMediaPlayer.release();
                            mMediaPlayer = null;
                        }
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        release();
    }

    public synchronized void reset() {
        Fast.logger.i(TAG, "reset..");
        if(mMediaPlayer!=null){
            try{
                mMediaPlayer.reset();
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }
    public  void release() {
        startTask();
        Fast.logger.i(TAG, "release..");
        MediaTask _task = new MediaTask();
        _task.what = TASK_MEDIA_RELEASE;
        basket.add(_task);
    }

    @Override
    public boolean isPlaying() {
        if(mMediaPlayer!=null){
            return mMediaPlayer.isPlaying();
        }
        return false;
    }

    @Override
    public int getDuration() {
        if(mMediaPlayer!=null){
            return mMediaPlayer.getDuration();
        }
        return 0;
    }

    @Override
    public int getCurrentPosition() {
        if(mMediaPlayer!=null){
            return mMediaPlayer.getCurrentPosition();
        }
        return 0;
    }

    @Override
    public void seekTo(int msec) {
        if(mMediaPlayer!=null){
            mMediaPlayer.seekTo(msec);
        }
    }
}
